package com.ideaaedi.zoo.diy.artifact.tenant.properties;

import com.ideaaedi.zoo.commonbase.component.auth.AuthUrlWhitelist;
import com.ideaaedi.zoo.commonbase.component.tenant.annotation.Tenant;
import com.ideaaedi.zoo.commonbase.util.ZooContext;
import com.ideaaedi.zoo.diy.artifact.tenant.properties.nested.TenantModeEnum;
import com.ideaaedi.zoo.diy.artifact.tenant.properties.nested.VisitorTenantInfo;
import com.ideaaedi.zoo.diy.artifact.tenant.tenant.TenantProvider;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;

import java.util.HashSet;
import java.util.Set;

/**
 * 租户相关配置
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
@Data
@ConfigurationProperties(prefix = "zoo.tenant")
public class ZooTenantProperties {
    
    /**
     * 租户过滤模式
     */
    @NotNull
    private TenantModeEnum mode = TenantModeEnum.LIKE_RIGHT;
    
    /**
     * 作为bizTenant的tenant的层级
     * <p>
     * 注：bizTenantLevel的值应大于1
     * </p>
     * <pre>
     * 如：租户 '1,'        的level=1
     * 如：租户 '1,2,'      的level=2
     * 如：租户 '1,2,10,'   的level=3
     * </pre>
     */
    private int bizTenantLevel = 2;
    
    /**
     * URD(修改、查询、删除)数据时，是否忽略租户过滤
     * <pre>
     * 注1：当此参数为true时，无论程序中是否还有使用{@link ZooContext.TenantCt}
     *     或 {@link TenantProvider} 或 {@link Tenant}指定URD租户值的操作，
     *     最终在进行URD操作时，都会忽略租户过滤。
     *     即：此字段的优先级最高
     *
     * 注2：此参数仅对修改、查询、删除操作生效，对新增操作不影响
     *      即1：通过{@link ZooContext.TenantCt} 或 {@link TenantProvider}
     *           或 {@link Tenant}指定新增数据时的租户值的操作，仍然有效
     *      即2：程序中，新增数据时，该需要租户值的，还是需要；不需要租户值得，还是不需要
     * </pre>
     */
    private boolean forceIgnoreUrd = false;
    
    /**
     * 游客租户信息
     * <pre>
     * 在{@link AuthUrlWhitelist}白名单下的请求，并不要求访问者具备登录态。
     *
     * 如果是一个没有登录态的请求（即：游客请求），那么此时是无法从上下文中获取
     * 到对应的租户信息的，这时，如果业务涉及到那些有租户要求的表的话，会因为获
     * 取用户租户信息失败而报错
     * 所以，这里对游客用户的请求，设置一个默认的租户信息
     * </pre>
     */
    @Valid
    @NestedConfigurationProperty
    private VisitorTenantInfo visitor = new VisitorTenantInfo();
    
    /**
     * 设置哪些表，允许用户查询租户值为null的数据
     * <pre>
     * 可能存在这样的需求：对于个别特殊表，允许所有用户查询tenant为null的数据。
     *                   此时，我们就可以通过此参数配置相关表
     * </pre>
     */
    @NotNull
    private Set<String> allowQueryNullTenantTables = new HashSet<>();
}
